#include <stdio.h>
#include "stm32f10x_gpio.h"

#include "lora.h"
#include "radio.h"
#include "sx1276-Hal.h"
#include "sx1276-Lora.h"

#include "lora_spi.h"

static tRadioDriver *radio_p = NULL;   // lora 初始化结构体

/**
 * @brief  LoRa 模组的初始化
 * @param  无
 * @retval 无
 */
void lora_module_init(void)
{
    // PIN_SPI_DataSize_8b, PIN_SPI_CPOL_Low, PIN_SPI_CPHA_1Edge
    
    lora_spi_init();    // LoRa模组SPI和IO初始化
    
    radio_p = RadioDriverInit();// LoRa驱动的初始化
    radio_p->Reset();
	radio_p->Init();
    get_loRa_module_vsion();
}


/**
 * @brief  拉低 LoRa 模组的复位引脚
 * @param  无
 * @retval 无
 */
void lora_reset_pin_set_low(void)
{
    GPIO_ResetBits(LORA_RST_PORT, LORA_RST_PIN);
}


/**
 * @brief  拉高 LoRa 模组的复位引脚
 * @param  无
 * @retval 无
 */
void lora_reset_pin_set_high(void)
{
    GPIO_SetBits(LORA_RST_PORT, LORA_RST_PIN);
}


/**
 * @brief  拉低 LoRa 模组的片选引脚
 * @param  无
 * @retval 无
 */
void lora_spi_nss_set_low(void)
{
    GPIO_ResetBits(LORA_SPI_NSS_PORT, LORA_SPI_NSS_PIN);
}


/**
 * @brief  拉高 LoRa 模组的片选引脚
 * @param  无
 * @retval 无
 */
void lora_spi_nss_set_high(void)
{
    GPIO_SetBits(LORA_SPI_NSS_PORT, LORA_SPI_NSS_PIN);
}


/**
 * @brief  读取 LoRa 模组的 DIO0 引脚的值
 * @param  无
 * @retval 读取到的值
 */
uint8_t lora_read_dio0_value(void)
{
    return GPIO_ReadInputDataBit(LORA_DIO0_PORT, LORA_DIO0_PIN);
}




/**
 * @brief  LoRa 模组 SPI读写函数
 * @param  要写入的数据
 * @retval 读到的数据
 */
uint8_t lora_spi_in_out(uint8_t outdata)
{
	return lora_spi_send_char( outdata );
}



/**
 * @brief  LoRa 开启接收
 * @param  无
 * @retval 无
 */
void lora_start_rx(void)
{
    if(radio_p == NULL) // 校验 lora 是否初始化
        return;
    
    radio_p->StartRx();
    read_lora_status();
}


/**
 * @brief  LoRa 发送数据包
 * @param  buff 指向要发送的数据的缓冲区
 * @param  len 要发送的数据的长度
 * @retval 无
 */
void lora_send_packet(uint8_t *buff, uint8_t len)
{
    if( (radio_p == NULL) || (buff == NULL) ) // 校验 lora 和 buff
        return;
    
    if(len > 32)    // 校验长度
        len = 32;
    
    radio_p->SetTxPacket( buff, len);	//发送数据
    read_lora_status();
}


/**
 * @brief  获取 LoRa 接收到的数据包
 * @param  指向存储接收数据的缓冲区
 * @param  接收数据的长度的指针
 * @retval 无
 */
void lora_get_rx_packet(uint8_t *buff, uint16_t *len)
{
    if(radio_p == NULL) // 校验 lora
        return;
   
    radio_p->GetRxPacket( buff, len );
}


/**
 * @brief  获取收到的数据包的 RSSI 值
 * @param  无
 * @retval 获取到的RSSI值，实际的值都是负值
 */
uint8_t get_lora_rssi(void)
{
    return (int)(-RxPacketRssiValue);
}


/**
 * @brief  获取收到数据包的SNR值
 * @param  无
 * @retval 获取到的SNR值
 */
uint8_t get_lora_snr(void)
{
    return (uint8_t)RxPacketSnrEstimate;
}


/**
 * @brief  获取 LoRa 的状态
 * @param  无
 * @retval LORA_IDLE，LORA_IDLE，LORA_RX_DONE，LORA_RX_TIMEOUT，LORA_TX_DONE, LORA_TX_TIMEOUT
 */                                  
loraStatus read_lora_status(void)
{
    uint32_t status;
    loraStatus ret = LORA_BUSY;
    
    if(radio_p == NULL) // 校验 lora
        return LORA_ERROR;
    
    status = radio_p->Process();
    switch(status)
    {
    case RF_IDLE:       ret = LORA_IDLE;        break;
    case RF_BUSY:       ret = LORA_BUSY;        break;
    case RF_RX_DONE:    ret = LORA_RX_DONE;     break;
    case RF_RX_TIMEOUT: ret = LORA_RX_TIMEOUT;  break;
    case RF_TX_DONE:    ret = LORA_TX_DONE;     break;
    case RF_TX_TIMEOUT: ret = LORA_TX_TIMEOUT;  break;
    default:                                    break;
    }
    
    return ret;
}


/**
 * @brief  获取 LoRa 版本号，校验模块是否好用
 * @param  无
 * @retval -1表示失败，0表示成功
 */
int get_loRa_module_vsion(void)
{
    uint8_t RegVer = 0;
		
    /* 获取版本号，寄存器地址是0x42 */
    SX1276Read( 0x42, &RegVer );
    if (RegVer == 0x12)
    {
        return 0;
    }
    else
    {
        return -1;
    }
}


/**
 * @brief  LoRa模组进入睡眠模式
 * @param  无
 * @retval -1表示失败，0表示成功
 */
void lora_module_enter_sleep_mode(void)
{
    SX1276LoRaSetOpMode( RFLR_OPMODE_SLEEP );
}


/**
 * @brief  LoRa模组复位
 * @param  无
 * @retval 无
 */
void lora_module_reset(void)
{
    radio_p->Reset();;
}
